package com.htfyun.ft.rooboUtils;

import android.media.AudioRecord;
import android.util.Log;

import com.htfyun.ft.common.FTUtils;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;


/**
 * Created by yuanshuqi on 2016/5/13 17:21.
 * email:yuanshuqi@roo.bo
 */
public class RooboRecorder {
    private static final String TAG = "RooboRecorder";
    private AudioRecord mAudioRecord;
    private int mRecBufSize;
    private byte[] mDataBuffer;
    private boolean mDestroy = false;
    private ExecutorService mReadExecutor;
    private Runnable mReadTask;
    private boolean mHasStart;

    private final OnReadDataListener listener;

    public interface OnReadDataListener {
        void onReadDataListener(byte[] data);
    }

    public RooboRecorder(OnReadDataListener l) {
        this.listener = l;

        mRecBufSize = AudioRecord.getMinBufferSize(AudioFileAttribute.AUDIO_SAMPLE_RATE,
                AudioFileAttribute.CHANNEL_CONFIGURATION, AudioFileAttribute.ENCODING_BIT_RATE);
        mReadTask = new ReadRunnable();
        mDataBuffer = new byte[mRecBufSize];
    }

    private class ReadRunnable implements Runnable {

        private final String RECORDER_FILE_PATH = FTUtils.getFTStorageDirectory() + File.separator + "wakeup.pcm";

        @Override
        public void run() {

            String recordPath = RECORDER_FILE_PATH;

            if (mAudioRecord == null) {
                return;
            }

            FileOutputStream fos = null;
            try {
                File file = new File(recordPath);
                if (file.exists()) {
                    file.delete();
                }
                file.createNewFile();
                fos = new FileOutputStream(file);// 建立一个可存取字节的文件
            } catch (Exception e) {
                e.printStackTrace();
                fos = null;
            }

            mAudioRecord.startRecording();
            Log.e(TAG, "RooboRecorder begin recording... mDestroy = " + mDestroy + ",mAudioRecord = " + mAudioRecord);
            while (!mDestroy) {

                if (mAudioRecord == null) {
                    break;
                }
                int len = 0;
                try {
                    len = mAudioRecord.read(mDataBuffer, 0, mRecBufSize);
                    byte[] data = new byte[len];
                    System.arraycopy(mDataBuffer, 0, data, 0, len);
                    if (fos != null) {
                        try {
                            fos.write(data);
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }

                    if (listener != null) {
                        listener.onReadDataListener(data);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }

            if (fos != null) {
                try {
                    fos.close();// 关闭写入流
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public void startRecord() {
        if (mHasStart) {
            Log.e(TAG, "has start record ,return");
            return;
        }
        mHasStart = true;
        mAudioRecord = new AudioRecord(AudioFileAttribute.AUDIO_INPUT,
                AudioFileAttribute.AUDIO_SAMPLE_RATE, AudioFileAttribute.CHANNEL_CONFIGURATION,
                AudioFileAttribute.ENCODING_BIT_RATE, mRecBufSize * 2);
        mReadExecutor = Executors.newSingleThreadExecutor();
        mDestroy = false;
        mReadExecutor.submit(mReadTask);
    }

    public void destroyRecorder() {
        Log.d(TAG, "1648k 16K destroyRecorder called");
        mHasStart = false;
        mDestroy = true;
        if (mAudioRecord != null) {
            mAudioRecord.stop();
            mAudioRecord.release();
            mAudioRecord = null;
        }
        if (mReadExecutor != null) {
            mReadExecutor.shutdownNow();
            mReadExecutor = null;
        }
    }
}
